# -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from openerp.osv import fields, osv
from openerp.tools.translate import _
import openerp.addons.decimal_precision as dp
import time

class param_create_quotation_analytic(osv.osv_memory):
    _name = 'param.create.quotation.analytic'
    _description = 'Create quotation Analytic'
    
    def _get_journal(self, cr, uid, context=None):
        journal_obj = self.pool.get('account.journal')
        journals = journal_obj.search(cr, uid, [('type', '=', 'sale')])
        return journals and journals[0] or False
    
    _columns = {
        'billing_type':fields.selection([('bill','Actual'),
                                 ('unbill','Non Actual'),
                                 ], 'Labour Billing Type'),
        'date_invoice': fields.date('Invoice Date'),
        'exchange_rate': fields.float('Invoice Exchange Rate', digits=(12,6), help='Change Currency Rate'),
        'journal_id': fields.many2one('account.journal', 'Destination Journal', required=True),
        'currency_id': fields.many2one('res.currency','Currency', readonly=True, required=True),
        'ship_normal_product_id': fields.many2one('product.product', 'Normal Product', domain=[('type','=','service')]),
        'ship_ot_product_id': fields.many2one('product.product', 'OT Product', domain=[('type','=','service')]),
        'ship_actual_normal_hours': fields.float('Normal Hour(s)'),
        'ship_actual_ot_hours': fields.float('OT Hour(s)'),
        'ship_normal_price': fields.float('Normal Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'ship_ot_price': fields.float('OT Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'real_ship_actual_normal_hours': fields.float('Can Process Hour(s)'),
        'real_ship_actual_ot_hours': fields.float('Can Process Hour(s)'),
        'mech_normal_product_id': fields.many2one('product.product', 'Normal Product', domain=[('type','=','service')]),
        'mech_ot_product_id': fields.many2one('product.product', 'OT Product', domain=[('type','=','service')]),
        'mech_actual_normal_hours': fields.float('Normal Hour(s)'),
        'mech_actual_ot_hours': fields.float('OT Hour(s)'),
        'mech_normal_price': fields.float('Normal Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'mech_ot_price': fields.float('OT Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'real_mech_actual_normal_hours': fields.float('Can Process Hour(s)'),
        'real_mech_actual_ot_hours': fields.float('Can Process Hour(s)'),
        'elec_normal_product_id': fields.many2one('product.product', 'Normal Product', domain=[('type','=','service')]),
        'elec_ot_product_id': fields.many2one('product.product', 'OT Product', domain=[('type','=','service')]),
        'elec_actual_normal_hours': fields.float('Normal Hour(s)'),
        'elec_actual_ot_hours': fields.float('OT Hour(s)'),
        'elec_normal_price': fields.float('Normal Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'elec_ot_price': fields.float('OT Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'real_elec_actual_normal_hours': fields.float('Can Process Hour(s)'),
        'real_elec_actual_ot_hours': fields.float('Can Process Hour(s)'),
        'weld_normal_product_id': fields.many2one('product.product', 'Normal Product', domain=[('type','=','service')]),
        'weld_ot_product_id': fields.many2one('product.product', 'OT Product', domain=[('type','=','service')]),
        'weld_actual_normal_hours': fields.float('Normal Hour(s)'),
        'weld_actual_ot_hours': fields.float('OT Hour(s)'),
        'weld_normal_price': fields.float('Normal Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'weld_ot_price': fields.float('OT Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'real_weld_actual_normal_hours': fields.float('Can Process Hour(s)'),
        'real_weld_actual_ot_hours': fields.float('Can Process Hour(s)'),
        'int_normal_product_id': fields.many2one('product.product', 'Normal Product', domain=[('type','=','service')]),
        'int_ot_product_id': fields.many2one('product.product', 'OT Product', domain=[('type','=','service')]),
        'int_actual_normal_hours': fields.float('Normal Hour(s)'),
        'int_actual_ot_hours': fields.float('OT Hour(s)'),
        'int_normal_price': fields.float('Normal Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'int_ot_price': fields.float('OT Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'real_int_actual_normal_hours': fields.float('Can Process Hour(s)'),
        'real_int_actual_ot_hours': fields.float('Can Process Hour(s)'),
        'desg_normal_product_id': fields.many2one('product.product', 'Normal Product', domain=[('type','=','service')]),
        'desg_ot_product_id': fields.many2one('product.product', 'OT Product', domain=[('type','=','service')]),
        'desg_actual_normal_hours': fields.float('Normal Hour(s)'),
        'desg_actual_ot_hours': fields.float('Normal Hour(s)'),
        'desg_normal_price': fields.float('Normal Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'desg_ot_price': fields.float('OT Price/Hour',digits_compute= dp.get_precision('Product Price')),
        'real_desg_actual_normal_hours': fields.float('Can Process Hour(s)'),
        'real_desg_actual_ot_hours': fields.float('Can Process Hour(s)'),
        'ship_inv_line_ids':fields.one2many('param.create.quotation.analytic.line','invoice_analytic_id','Shipyard Invoice Lines',
            domain=[('type','=','shipyard')], context={'default_type':'shipyard'}),
        'mech_inv_line_ids':fields.one2many('param.create.quotation.analytic.line','invoice_analytic_id','Mechanical Invoice Lines',
            domain=[('type','=','mechanical')], context={'default_type':'mechanical'}),
        'elec_inv_line_ids':fields.one2many('param.create.quotation.analytic.line','invoice_analytic_id','Electrical Invoice Lines',
            domain=[('type','=','electrical')], context={'default_type':'electrical'}),
        'weld_inv_line_ids':fields.one2many('param.create.quotation.analytic.line','invoice_analytic_id','Welding & Fabrication Invoice Lines',
            domain=[('type','=','welding_fabrication')], context={'default_type':'welding_fabrication'}),
        'int_inv_line_ids':fields.one2many('param.create.quotation.analytic.line','invoice_analytic_id','Interior Invoice Lines',
            domain=[('type','=','interior')], context={'default_type':'interior'}),
        'desg_inv_line_ids':fields.one2many('param.create.quotation.analytic.line','invoice_analytic_id','Design Invoice Lines',
            domain=[('type','=','design')], context={'default_type':'design'}),
        'ship_service_line_ids':fields.one2many('param.create.quotation.analytic.service.line','invoice_analytic_service_id','Shipyard',
            domain=[('type','=','shipyard')], context={'default_type':'shipyard'}),
        'mech_service_line_ids':fields.one2many('param.create.quotation.analytic.service.line','invoice_analytic_service_id','Mechanical',
            domain=[('type','=','mechanical')], context={'default_type':'mechanical'}),
        'elec_service_line_ids':fields.one2many('param.create.quotation.analytic.service.line','invoice_analytic_service_id','Electrical',
            domain=[('type','=','electrical')], context={'default_type':'electrical'}),
        'weld_service_line_ids':fields.one2many('param.create.quotation.analytic.service.line','invoice_analytic_service_id','Welding & Fabrication',
            domain=[('type','=','welding_fabrication')], context={'default_type':'welding_fabrication'}),
        'int_service_line_ids':fields.one2many('param.create.quotation.analytic.service.line','invoice_analytic_service_id','Interior',
            domain=[('type','=','interior')], context={'default_type':'interior'}),
        'desg_service_line_ids':fields.one2many('param.create.quotation.analytic.service.line','invoice_analytic_service_id','Design',
            domain=[('type','=','design')], context={'default_type':'design'}),
    }
    _defaults = {
        'journal_id': _get_journal,
    }
    
    def onchange_ship_actual_normal_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}

        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual normal hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'ship_actual_normal_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}
    
    def onchange_ship_actual_ot_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}
        
        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual OT hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'ship_actual_ot_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}
    
    def onchange_mech_actual_normal_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}

        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual normal hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'mech_actual_normal_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}
    
    def onchange_mech_actual_ot_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}
        
        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual OT hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'mech_actual_ot_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}
    
    def onchange_elec_actual_normal_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}

        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual normal hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'elec_actual_normal_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}
    
    def onchange_elec_actual_ot_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}

        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual OT hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'elec_actual_ot_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}
    
    def onchange_weld_actual_normal_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}

        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual normal hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'weld_actual_normal_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}
    
    def onchange_weld_actual_ot_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}

        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual OT hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'weld_actual_ot_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}

    def onchange_int_actual_normal_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}

        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual normal hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'int_actual_normal_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}
    
    def onchange_int_actual_ot_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}

        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual OT hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'int_actual_ot_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}
    
    def onchange_desg_actual_normal_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}

        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual normal hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'desg_actual_normal_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}
    
    def onchange_desg_actual_ot_qty(self, cr, uid, ids, billing_type, real_qty, qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}

        if qty > real_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The hour(s) you entered cannot be more than actual OT hour(s) (%s)!.') % (real_qty,)
                       }
             
            value = {
                     'desg_actual_ot_hours' : real_qty,
                    }
         
        return {'value': value,
                'warning': warning}
    
    def _fill_data_inv(self, cr, uid, val_ids, context=None):
        product_uom_obj = self.pool.get('product.uom')
        inv_lines = []

        if context is None:
            context = {}
        
        if val_ids:
            for inv in val_ids:
                can_process_qty = inv.process_qty - inv.invoices_qty
                if can_process_qty > 0:
                    min_uom_qty = product_uom_obj._compute_qty(cr, uid, inv.product_uom.id, 1, inv.product_id.uom_id.id)
                    product_uom = False
                    quantity = unit_price = 0
                    if can_process_qty%min_uom_qty == 0:
                        quantity = product_uom_obj._compute_qty(cr, uid, inv.product_id.uom_id.id, can_process_qty, inv.product_uom.id)
                        product_uom = inv.product_uom.id
                        unit_price = inv.unit_price
                    else:
                        product_uom = inv.product_id.uom_id.id
                        quantity = can_process_qty
                        unit_price = product_uom_obj._compute_price(cr, uid, inv.product_uom.id, inv.unit_price,
                                                                    inv.product_id.uom_id.id)
                    item = {
                        'product_id': inv.product_id.id,
                        'product_qty': inv.product_qty,
                        'product_uom': inv.product_uom.id,
                        'unit_price': inv.unit_price,
                        'real_qty': inv.real_qty,
                        'generated_qty': can_process_qty,
                        'process_qty': quantity,
                        'sel_product_uom': product_uom,
                        'sel_unit_price': unit_price,
                        'analytic_line_id': inv.id,
                    }
                    inv_lines.append(item)
        
        return inv_lines
    
    def _fill_data_srvc(self, cr, uid, val_ids, context=None):
        service_inv_lines = []

        if context is None:
            context = {}
            
        if val_ids: 
            for service in val_ids:
                can_process_qty = service.product_qty - service.invoices_service_qty
                if can_process_qty > 0:
                    item = {
                        'product_id': service.product_id.id,
                        'real_product_qty': can_process_qty,
                        'product_qty': can_process_qty,
                        'unit_price': service.unit_price,
                        'analytic_service_line_id': service.id,
                    }
                    service_inv_lines.append(item)
        
        return service_inv_lines
                 
    def default_get(self, cr, uid, fields, context=None):
        if context is None:
            context = {}
        acc_analytic_obj = self.pool.get('account.analytic.account')
        product_uom_obj = self.pool.get('product.uom')
        
        res = super(param_create_quotation_analytic, self).default_get(cr, uid, fields, context=context)
        ship_inv_lines = []
        mech_inv_lines = []
        elec_inv_lines = []
        weld_inv_lines = []
        int_inv_lines  = []
        desg_inv_lines = []
        
        ship_service_lines = []
        mech_service_lines = []
        elec_service_lines = []
        weld_service_lines = []
        int_service_lines  = []
        desg_service_lines = []
        
        for lines in acc_analytic_obj.browse(cr, uid, context.get(('active_ids'), []), context=context):            
            
            if not lines.billing_type:
                raise osv.except_osv(_('Invalid Action!'), _('Please select billing type first before proceed!'))
            else:
                res.update({'billing_type': lines.billing_type})
            res.update({'billing_type': lines.billing_type})
            res.update({'currency_id': lines.currency_id.id})
            
            if lines.sy_normal_product_id:
                res.update({'ship_normal_product_id': lines.sy_normal_product_id.id})
            if lines.sy_ot_product_id:
                res.update({'ship_ot_product_id': lines.sy_ot_product_id.id})
            if lines.sy_normal_price:
                res.update({'ship_normal_price': lines.sy_normal_price})
            if lines.sy_ot_price:
                res.update({'ship_ot_price': lines.sy_ot_price})
            
            if lines.mech_normal_product_id:
                res.update({'mech_normal_product_id': lines.mech_normal_product_id.id})
            if lines.mech_ot_product_id:
                res.update({'mech_ot_product_id': lines.mech_ot_product_id.id})
            if lines.mech_normal_price:
                res.update({'mech_normal_price': lines.mech_normal_price})
            if lines.mech_ot_price:
                res.update({'mech_ot_price': lines.mech_ot_price})
             
            if lines.elec_normal_product_id:
                res.update({'elec_normal_product_id': lines.elec_normal_product_id.id})
            if lines.elec_ot_product_id:
                res.update({'elec_ot_product_id': lines.elec_ot_product_id.id})
            if lines.elec_normal_price:
                res.update({'elec_normal_price': lines.elec_normal_price})
            if lines.elec_ot_price:
                res.update({'elec_ot_price': lines.elec_ot_price})
             
            if lines.weld_normal_product_id:
                res.update({'weld_normal_product_id': lines.weld_normal_product_id.id})
            if lines.weld_ot_product_id:
                res.update({'weld_ot_product_id': lines.weld_ot_product_id.id})
            if lines.weld_normal_price:
                res.update({'weld_normal_price': lines.weld_normal_price})
            if lines.weld_ot_price:
                res.update({'weld_ot_price': lines.weld_ot_price})
             
            if lines.int_normal_product_id:
                res.update({'int_normal_product_id': lines.int_normal_product_id.id})
            if lines.int_ot_product_id:
                res.update({'int_ot_product_id': lines.int_ot_product_id.id})
            if lines.int_normal_price:
                res.update({'int_normal_price': lines.int_normal_price})
            if lines.int_ot_price:
                res.update({'int_ot_price': lines.int_ot_price})
                 
            if lines.desg_normal_product_id:
                res.update({'desg_normal_product_id': lines.desg_normal_product_id.id})
            if lines.desg_ot_product_id:
                res.update({'desg_ot_product_id': lines.desg_ot_product_id.id})
            if lines.desg_normal_price:
                res.update({'desg_normal_price': lines.desg_normal_price})
            if lines.desg_ot_price:
                res.update({'desg_ot_price': lines.desg_ot_price})
             
            if lines.billing_type == 'bill':
                if lines.sy_actual_normal_hours > 0:
                    res.update({'real_ship_actual_normal_hours': lines.sy_actual_normal_hours - lines.sy_normal_invoice_qty})
                    res.update({'ship_actual_normal_hours': lines.sy_actual_normal_hours - lines.sy_normal_invoice_qty})
                if lines.sy_actual_ot_hours > 0:
                    res.update({'real_ship_actual_ot_hours': lines.sy_actual_ot_hours - lines.sy_ot_invoice_qty})
                    res.update({'ship_actual_ot_hours': lines.sy_actual_ot_hours - lines.sy_ot_invoice_qty})
                if lines.mech_actual_normal_hours > 0:
                    res.update({'real_mech_actual_normal_hours': lines.mech_actual_normal_hours - lines.mech_normal_invoice_qty})
                    res.update({'mech_actual_normal_hours': lines.mech_actual_normal_hours - lines.mech_normal_invoice_qty})
                if lines.mech_actual_ot_hours > 0:
                    res.update({'real_mech_actual_ot_hours': lines.mech_actual_ot_hours - lines.mech_ot_invoice_qty})
                    res.update({'mech_actual_ot_hours': lines.mech_actual_ot_hours - lines.mech_ot_invoice_qty})
                if lines.elec_actual_normal_hours > 0:
                    res.update({'real_elec_actual_normal_hours': lines.elec_actual_normal_hours - lines.elec_normal_invoice_qty})
                    res.update({'elec_actual_normal_hours': lines.elec_actual_normal_hours - lines.elec_normal_invoice_qty})
                if lines.elec_actual_ot_hours > 0:
                    res.update({'real_elec_actual_ot_hours': lines.elec_actual_ot_hours - lines.elec_ot_invoice_qty})
                    res.update({'elec_actual_ot_hours': lines.elec_actual_ot_hours - lines.elec_ot_invoice_qty})
                if lines.weld_actual_normal_hours > 0:
                    res.update({'real_weld_actual_normal_hours': lines.weld_actual_normal_hours - lines.weld_normal_invoice_qty})
                    res.update({'weld_actual_normal_hours': lines.weld_actual_normal_hours - lines.weld_normal_invoice_qty})
                if lines.weld_actual_ot_hours > 0:
                    res.update({'real_weld_actual_ot_hours': lines.weld_actual_ot_hours - lines.weld_ot_invoice_qty})
                    res.update({'weld_actual_ot_hours': lines.weld_actual_ot_hours - lines.weld_ot_invoice_qty})
                if lines.int_actual_normal_hours > 0:
                    res.update({'real_int_actual_normal_hours': lines.int_actual_normal_hours - lines.int_normal_invoice_qty})
                    res.update({'int_actual_normal_hours': lines.int_actual_normal_hours - lines.int_normal_invoice_qty})
                if lines.int_actual_ot_hours > 0:
                    res.update({'real_int_actual_ot_hours': lines.int_actual_ot_hours - lines.int_ot_invoice_qty})
                    res.update({'int_actual_ot_hours': lines.int_actual_ot_hours - lines.int_ot_invoice_qty})
                if lines.desg_actual_normal_hours > 0:
                    res.update({'real_desg_actual_normal_hours': lines.desg_actual_normal_hours - lines.desg_normal_invoice_qty})
                    res.update({'desg_actual_normal_hours': lines.desg_actual_normal_hours - lines.desg_normal_invoice_qty})
                if lines.desg_actual_ot_hours > 0:
                    res.update({'real_desg_actual_ot_hours': lines.desg_actual_ot_hours - lines.desg_ot_invoice_qty})
                    res.update({'desg_actual_ot_hours': lines.desg_actual_ot_hours - lines.desg_ot_invoice_qty})
            else:
                if lines.sy_normal_qty > 0:
                    res.update({'real_ship_actual_normal_hours': lines.sy_normal_qty - lines.sy_normal_invoice_qty})
                    res.update({'ship_actual_normal_hours': lines.sy_normal_qty - lines.sy_normal_invoice_qty})
                if lines.sy_ot_qty > 0:    
                    res.update({'real_ship_actual_ot_hours': lines.sy_ot_qty - lines.sy_ot_invoice_qty})
                    res.update({'ship_actual_ot_hours': lines.sy_ot_qty - lines.sy_ot_invoice_qty})
                if lines.mech_normal_qty > 0:
                    res.update({'real_mech_actual_normal_hours': lines.mech_normal_qty - lines.mech_normal_invoice_qty})
                    res.update({'mech_actual_normal_hours': lines.mech_normal_qty - lines.mech_normal_invoice_qty})
                if lines.mech_ot_qty > 0:    
                    res.update({'real_mech_actual_ot_hours': lines.mech_ot_qty - lines.mech_ot_invoice_qty})
                    res.update({'mech_actual_ot_hours': lines.mech_ot_qty - lines.mech_ot_invoice_qty})
                if lines.elec_normal_qty > 0:
                    res.update({'real_elec_actual_normal_hours': lines.elec_normal_qty - lines.elec_normal_invoice_qty})
                    res.update({'elec_actual_normal_hours': lines.elec_normal_qty - lines.elec_normal_invoice_qty})
                if lines.elec_ot_qty > 0:    
                    res.update({'real_elec_actual_ot_hours': lines.elec_ot_qty - lines.elec_ot_invoice_qty})
                    res.update({'elec_actual_ot_hours': lines.elec_ot_qty - lines.elec_ot_invoice_qty})
                if lines.weld_normal_qty > 0:
                    res.update({'real_weld_actual_normal_hours': lines.weld_normal_qty - lines.weld_normal_invoice_qty})
                    res.update({'weld_actual_normal_hours': lines.weld_normal_qty - lines.weld_normal_invoice_qty})
                if lines.weld_ot_qty > 0:    
                    res.update({'real_weld_actual_ot_hours': lines.weld_ot_qty - lines.weld_ot_invoice_qty})
                    res.update({'weld_actual_ot_hours': lines.weld_ot_qty - lines.weld_ot_invoice_qty})
                if lines.int_normal_qty > 0:
                    res.update({'real_int_actual_normal_hours': lines.int_normal_qty - lines.int_normal_invoice_qty})
                    res.update({'int_actual_normal_hours': lines.int_normal_qty - lines.int_normal_invoice_qty})
                if lines.int_ot_qty > 0:    
                    res.update({'real_int_actual_ot_hours': lines.int_ot_qty - lines.int_ot_invoice_qty})
                    res.update({'int_actual_ot_hours': lines.int_ot_qty - lines.int_ot_invoice_qty}) 
                if lines.desg_normal_qty > 0:
                    res.update({'real_desg_actual_normal_hours': lines.desg_normal_qty - lines.desg_normal_invoice_qty})
                    res.update({'desg_actual_normal_hours': lines.desg_normal_qty - lines.desg_normal_invoice_qty})
                if lines.desg_ot_qty > 0:    
                    res.update({'real_desg_actual_ot_hours': lines.desg_ot_qty - lines.desg_ot_invoice_qty})
                    res.update({'desg_actual_ot_hours': lines.desg_ot_qty - lines.desg_ot_invoice_qty})
                
            
            
            ship_inv_lines = self._fill_data_inv(cr, uid, lines.shipyard_line_ids, context=context)
            if ship_inv_lines:
                res.update({'ship_inv_line_ids': ship_inv_lines})
                 
            mech_inv_lines = self._fill_data_inv(cr, uid, lines.mechanical_line_ids, context=context)
            if mech_inv_lines:
                res.update({'mech_inv_line_ids': mech_inv_lines})
                 
            elec_inv_lines = self._fill_data_inv(cr, uid, lines.electrical_line_ids, context=context)
            if elec_inv_lines:
                res.update({'elec_inv_line_ids': elec_inv_lines})
                 
            weld_inv_lines = self._fill_data_inv(cr, uid, lines.welding_line_ids, context=context)
            if weld_inv_lines:
                res.update({'elec_inv_line_ids': weld_inv_lines})
             
            int_inv_lines = self._fill_data_inv(cr, uid, lines.interior_line_ids, context=context)
            if int_inv_lines:
                res.update({'int_inv_line_ids': int_inv_lines})
                 
            desg_inv_lines = self._fill_data_inv(cr, uid, lines.design_line_ids, context=context)
            if desg_inv_lines:
                res.update({'desg_inv_line_ids': desg_inv_lines})
             
            ship_service_lines = self._fill_data_srvc(cr, uid, lines.ship_service_line_ids, context=context)
            if ship_service_lines:
                res.update({'ship_service_line_ids': ship_service_lines})
            
            mech_service_lines = self._fill_data_srvc(cr, uid, lines.mech_service_line_ids, context=context)
            if mech_service_lines:
                res.update({'mech_service_line_ids': mech_service_lines})
            
            elec_service_lines = self._fill_data_srvc(cr, uid, lines.elec_service_line_ids, context=context)
            if elec_service_lines:
                res.update({'elec_service_line_ids': elec_service_lines})
            
            weld_service_lines = self._fill_data_srvc(cr, uid, lines.weld_service_line_ids, context=context)
            if weld_service_lines:
                res.update({'weld_service_line_ids': weld_service_lines})
            
            int_service_lines = self._fill_data_srvc(cr, uid, lines.int_service_line_ids, context=context)
            if int_service_lines:
                res.update({'int_service_line_ids': int_service_lines})
            
            desg_service_lines = self._fill_data_srvc(cr, uid, lines.desg_service_line_ids, context=context)
            if desg_service_lines:
                res.update({'desg_service_line_ids': desg_service_lines})
            
        return res
    
    def _prepare_data_inv(self, cr, uid, val_ids, type, context=None):
        if context is None:
            context = {}
        item = {}
         
        if val_ids: 
            for inv in val_ids: 
                account_id_inv = inv.product_id.property_account_income.id
                if not account_id_inv:
                    account_id_inv = inv.product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': inv.product_id.name,
                    'account_id': account_id_inv,
                    'product_id': inv.product_id.id,
                    'uos_id': inv.sel_product_uom.id,
                    'quantity': inv.process_qty,
                    'price_unit': inv.sel_unit_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'analytic_line_id': inv.analytic_line_id,
                    'type': type,
                    'ot_flag': False,
                    }
        
        return item
    
    def _prepare_data_srvc(self, cr, uid, val_ids, type, context=None):
        if context is None:
            context = {}
        item = {}
         
        if val_ids: 
            for service in val_ids: 
                account_id_service = service.product_id.property_account_income.id
                if not account_id_service:
                    account_id_service = service.product_id.categ_id.property_account_income_categ.id
                    item = {
                        'name': service.product_id.name,
                        'account_id': account_id_service,
                        'product_id': service.product_id.id,
                        'uos_id': service.product_id.uom_id.id,
                        'quantity': service.product_qty,
                        'price_unit': service.unit_price,
                        'discount': 0.0,
                        'account_analytic_id': False,
                        'analytic_service_line_id': service.analytic_service_line_id,
                        'type': type,
                        'ot_flag': False,
                    }
        
        return item
    
    def generate_analytic_invoice(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        
        wizard = self.browse(cr, uid, ids[0], context)
        ship_inv_lines = {}
        mech_inv_lines = {}
        elec_inv_lines = {}
        weld_inv_lines = {}
        int_inv_lines  = {}
        desg_inv_lines = {} 
        ship_srvc_lines = {}
        mech_srvc_lines = {}
        elec_srvc_lines = {}
        weld_srvc_lines = {}
        int_srvc_lines  = {}
        desg_srvc_lines = {}
        
        analytic_inv_lines = []
        
        if wizard.ship_normal_product_id:
            if wizard.ship_actual_normal_hours > 0:
                account_id_lab = wizard.ship_normal_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.ship_normal_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.ship_normal_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.ship_normal_product_id.id,
                    'uos_id': wizard.ship_normal_product_id.uom_id.id,
                    'quantity': wizard.ship_actual_normal_hours,
                    'price_unit': wizard.ship_normal_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'shipyard',
                    'ot_flag': False,
                    }
                    analytic_inv_lines.append(item)
        
        if wizard.ship_ot_product_id:
            if wizard.ship_actual_ot_hours > 0:
                account_id_lab = wizard.ship_ot_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.ship_ot_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.ship_ot_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.ship_ot_product_id.id,
                    'uos_id': wizard.ship_ot_product_id.uom_id.id,
                    'quantity': wizard.ship_actual_ot_hours,
                    'price_unit': wizard.ship_ot_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'shipyard',
                    'ot_flag': True,
                    }
                    analytic_inv_lines.append(item)
        
        if wizard.mech_normal_product_id:
            if wizard.mech_actual_normal_hours > 0:
                account_id_lab = wizard.mech_normal_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.mech_normal_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.mech_normal_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.mech_normal_product_id.id,
                    'uos_id': wizard.mech_normal_product_id.uom_id.id,
                    'quantity': wizard.mech_actual_normal_hours,
                    'price_unit': wizard.mech_normal_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'mechanical',
                    'ot_flag': False,
                    }
                    analytic_inv_lines.append(item)
        
        if wizard.mech_ot_product_id:
            if wizard.mech_actual_ot_hours > 0:
                account_id_lab = wizard.mech_ot_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.mech_ot_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.mech_ot_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.mech_ot_product_id.id,
                    'uos_id': wizard.mech_ot_product_id.uom_id.id,
                    'quantity': wizard.mech_actual_ot_hours,
                    'price_unit': wizard.mech_ot_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'mechanical',
                    'ot_flag': True,
                    }
                    analytic_inv_lines.append(item)
        
        if wizard.elec_normal_product_id:
            if wizard.elec_actual_normal_hours > 0:
                account_id_lab = wizard.elec_normal_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.elec_normal_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.elec_normal_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.elec_normal_product_id.id,
                    'uos_id': wizard.elec_normal_product_id.uom_id.id,
                    'quantity': wizard.elec_actual_normal_hours,
                    'price_unit': wizard.elec_normal_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'electrical',
                    'ot_flag': False,
                    }
                    analytic_inv_lines.append(item)
        
        if wizard.elec_ot_product_id:
            if wizard.elec_actual_ot_hours > 0:
                account_id_lab = wizard.elec_ot_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.elec_ot_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.elec_ot_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.elec_ot_product_id.id,
                    'uos_id': wizard.elec_ot_product_id.uom_id.id,
                    'quantity': wizard.elec_actual_ot_hours,
                    'price_unit': wizard.elec_ot_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'electrical',
                    'ot_flag': True,
                    }
                    analytic_inv_lines.append(item)
        
        if wizard.weld_normal_product_id:
            if wizard.weld_actual_normal_hours > 0:
                account_id_lab = wizard.weld_normal_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.weld_normal_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.weld_normal_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.weld_normal_product_id.id,
                    'uos_id': wizard.weld_normal_product_id.uom_id.id,
                    'quantity': wizard.weld_actual_normal_hours,
                    'price_unit': wizard.weld_normal_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'welding_fabrication',
                    'ot_flag': False,
                    }
                    analytic_inv_lines.append(item)
        
        if wizard.weld_ot_product_id:
            if wizard.weld_actual_ot_hours > 0:
                account_id_lab = wizard.weld_ot_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.weld_ot_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.weld_ot_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.weld_ot_product_id.id,
                    'uos_id': wizard.weld_ot_product_id.uom_id.id,
                    'quantity': wizard.weld_actual_ot_hours,
                    'price_unit': wizard.weld_ot_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'welding_fabrication',
                    'ot_flag': True,
                    }
                    analytic_inv_lines.append(item)
        
        if wizard.int_normal_product_id:
            if wizard.int_actual_normal_hours > 0:
                account_id_lab = wizard.int_normal_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.int_normal_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.int_normal_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.int_normal_product_id.id,
                    'uos_id': wizard.int_normal_product_id.uom_id.id,
                    'quantity': wizard.int_actual_normal_hours,
                    'price_unit': wizard.int_normal_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'interior',
                    'ot_flag': False,
                    }
                    analytic_inv_lines.append(item)
        
        if wizard.int_ot_product_id:
            if wizard.int_actual_ot_hours > 0:
                account_id_lab = wizard.int_ot_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.int_ot_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.int_ot_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.int_ot_product_id.id,
                    'uos_id': wizard.int_ot_product_id.uom_id.id,
                    'quantity': wizard.int_actual_ot_hours,
                    'price_unit': wizard.int_ot_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'interior',
                    'ot_flag': True,
                    }
                    analytic_inv_lines.append(item)
        
        if wizard.desg_normal_product_id:
            if wizard.desg_actual_normal_hours > 0:
                account_id_lab = wizard.desg_normal_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.desg_normal_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.desg_normal_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.desg_normal_product_id.id,
                    'uos_id': wizard.desg_normal_product_id.uom_id.id,
                    'quantity': wizard.desg_actual_normal_hours,
                    'price_unit': wizard.desg_normal_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'design',
                    'ot_flag': False,
                    }
                    analytic_inv_lines.append(item)
        
        if wizard.desg_ot_product_id:
            if wizard.desg_actual_ot_hours > 0:
                account_id_lab = wizard.desg_ot_product_id.property_account_income.id
                if not account_id_lab:
                    account_id_lab = wizard.desg_ot_product_id.categ_id.property_account_income_categ.id
                    item = {
                    'name': wizard.desg_ot_product_id.name,
                    'account_id': account_id_lab,
                    'product_id': wizard.desg_ot_product_id.id,
                    'uos_id': wizard.desg_ot_product_id.uom_id.id,
                    'quantity': wizard.desg_actual_ot_hours,
                    'price_unit': wizard.desg_ot_price,
                    'discount': 0.0,
                    'account_analytic_id': False,
                    'type': 'design',
                    'ot_flag': True,
                    }
                    analytic_inv_lines.append(item)
            
        ship_srvc_lines = self._prepare_data_srvc(cr, uid, wizard.ship_service_line_ids, 'shipyard', context=context)
        if ship_srvc_lines:
            analytic_inv_lines.append(ship_srvc_lines)
        
        mech_srvc_lines = self._prepare_data_srvc(cr, uid, wizard.mech_service_line_ids, 'mechanical', context=context)
        if mech_srvc_lines:
            analytic_inv_lines.append(mech_srvc_lines)
            
        elec_srvc_lines = self._prepare_data_srvc(cr, uid, wizard.elec_service_line_ids, 'electrical', context=context)
        if elec_srvc_lines:
            analytic_inv_lines.append(elec_srvc_lines)
            
        weld_srvc_lines = self._prepare_data_srvc(cr, uid, wizard.weld_service_line_ids, 'welding_fabrication', context=context)
        if weld_srvc_lines:
            analytic_inv_lines.append(weld_srvc_lines)
        
        int_srvc_lines = self._prepare_data_srvc(cr, uid, wizard.int_service_line_ids, 'interior', context=context)
        if int_srvc_lines:
            analytic_inv_lines.append(int_srvc_lines)
        
        desg_srvc_lines = self._prepare_data_srvc(cr, uid, wizard.desg_service_line_ids, 'design', context=context)
        if desg_srvc_lines:
            analytic_inv_lines.append(desg_srvc_lines)
        
        ship_inv_lines = self._prepare_data_inv(cr, uid, wizard.ship_inv_line_ids, 'shipyard', context=context)
        if ship_inv_lines:
            analytic_inv_lines.append(ship_inv_lines)
        
        mech_inv_lines = self._prepare_data_inv(cr, uid, wizard.mech_inv_line_ids, 'mechanical', context=context)
        if mech_inv_lines:
            analytic_inv_lines.append(mech_inv_lines)
        
        elec_inv_lines = self._prepare_data_inv(cr, uid, wizard.elec_inv_line_ids, 'electrical', context=context)
        if elec_inv_lines:
            analytic_inv_lines.append(elec_inv_lines)
        
        weld_inv_lines = self._prepare_data_inv(cr, uid, wizard.weld_inv_line_ids, 'welding_fabrication', context=context)
        if weld_inv_lines:
            analytic_inv_lines.append(weld_inv_lines)
        
        int_inv_lines = self._prepare_data_inv(cr, uid, wizard.int_inv_line_ids, 'interior', context=context)
        if int_inv_lines:
            analytic_inv_lines.append(int_inv_lines)
        
        desg_inv_lines = self._prepare_data_inv(cr, uid, wizard.desg_inv_line_ids, 'design', context=context)
        if desg_inv_lines:
            analytic_inv_lines.append(desg_inv_lines)
        
        if not analytic_inv_lines:
            raise osv.except_osv(_('Invalid Action!'), _('No materials and services to be invoiced, Please check carefully!'))
         
        invoice_id = self.create_invoice(cr, uid, ids, analytic_inv_lines, context=context)
        if not invoice_id:
            raise osv.except_osv(_('Error!'), _('No invoice created!'))

        data = self.browse(cr, uid, ids[0], context=context)
        action = {}
        
        inv_type = 'out_invoice'
        data_pool = self.pool.get('ir.model.data')
        if inv_type == "out_invoice":
            action_id = data_pool.xmlid_to_res_id(cr, uid, 'account.action_invoice_tree1')
            
        if action_id:
            action_pool = self.pool['ir.actions.act_window']
            action = action_pool.read(cr, uid, action_id, context=context)
            action['domain'] = "[('id','in', ["+','.join(map(str,[invoice_id,]))+"])]"
            return action
        return True

    def create_invoice(self, cr, uid, ids, analytic_inv_lines, context=None):
        context = dict(context or {})
        acc_analytic_pool = self.pool.get('account.analytic.account')
        res_currency_rate_obj = self.pool.get("res.currency.rate")
        
        data = self.browse(cr, uid, ids[0], context=context)
        cur_date = data.date_invoice or fields.date.context_today(self, cr, uid, context=context)
        exrate = 0
        
        if data.date_invoice:
            context['date_inv'] = data.date_invoice
        else:
            context['date_inv'] = time.strftime("%Y-%m-%d")
        
        if data.exchange_rate:
            context['exrate'] = data.exchange_rate
        else:
            res_currency_rate_ids = res_currency_rate_obj.search(cr, uid, [('currency_id', '=', data.currency_id.id), ('name', '<=', cur_date)], order='name DESC', limit=1)
            if res_currency_rate_ids:
                exrate = res_currency_rate_obj.browse(cr, uid, res_currency_rate_ids[0], context=context).rate
                context['exrate'] = exrate
             
        context['inv_type'] = 'out_invoice'
        
        active_ids = context.get('active_ids', [])
        invoice_id = acc_analytic_pool._analytic_invoice_create_line(cr, uid, active_ids,
              data.journal_id.id, analytic_inv_lines,
              'out_invoice',
              context=context)
        
        return invoice_id
    
class param_create_quotation_analytic_line(osv.osv_memory):
    _name = 'param.create.quotation.analytic.line'
    _description = 'Create Quotation Analytic Line'
    
    _columns = {
        'invoice_analytic_id': fields.many2one('param.create.invoice.analytic', 'Analytic Invoice', ondelete='cascade', readonly=True),
        'product_id': fields.many2one('product.product', 'Product', readonly=True),
        'product_qty': fields.float('Quantity', readonly=True),
        'unit_price': fields.float('Unit Price',digits_compute= dp.get_precision('Product Price'), readonly=True),
        'product_uom': fields.many2one('product.uom', 'Unit of Measure ', readonly=True),
        'type':fields.selection([('shipyard','Shipyard'),
                                 ('mechanical','Mechanical'),
                                 ('electrical','Electrical'),
                                 ('welding_fabrication','Welding & Fabrication'),
                                 ('interior','Interior'),
                                 ('design','Design')
                                 ], 'Type', readonly=True),
        'real_qty': fields.float('Real Quantity', readonly=True),
        'generated_qty': fields.float('Can Process Quantity', readonly=True),
        'sel_product_uom': fields.many2one('product.uom', 'UoM', required=True),
        'process_qty': fields.float('Quantity', required=True),
        'sel_unit_price': fields.float('Unit Price',digits_compute= dp.get_precision('Product Price'), required=True),
        'analytic_line_id': fields.char('Analytic Line Id', readonly=True),
    }
    
    def onchange_product_uom(self, cr, uid, ids, product_uom_asli, process_qty, product_id, quantity, product_uom, unit_price, context=None):
        if context is None:
            context = {}
        value = {}
        product_uom_obj = self.pool.get('product.uom')

        if (not product_id) or (not product_uom):
            value = {
                     'process_qty' : 0.00,
                     'sel_product_uom' : False,
                     }
            return {'value': value}
        
        product_product = self.pool.get('product.product').browse(cr, uid, [product_id])
        uom_id = product_product.uom_id
        product_uom = self.pool.get('product.uom').browse(cr, uid, [product_uom])
        if uom_id.category_id.id != product_uom.category_id.id:
            warning = {
                       'title': _('Warning'), 
                       'message': _('Conversion from Product UoM %s to Default UoM %s is not possible as they both belong to different Category!.') % (product_uom.category_id.name,uom_id.category_id.name,)
                       }
            min_uom_qty = product_uom_obj._compute_qty(cr, uid, product_uom_asli, 1, uom_id.id)
            if process_qty%min_uom_qty == 0:
                qty_value = product_uom_obj._compute_qty(cr, uid,uom_id.id, process_qty, product_uom_asli)
                uom_value = product_uom_asli
            else:
                uom_value = uom_id.id
                qty_value = process_qty
                unit_price = product_uom_obj._compute_price(cr, uid, product_uom_asli, unit_price,
                        uom_id.id)
            
            value = {
                     'process_qty' : qty_value,
                     'sel_product_uom' : uom_value,
                     'sel_unit_price' : unit_price,
                    }
            return {'value': value,
                    'warning': warning}
        q = product_uom_obj._compute_qty(cr, uid, product_uom.id, quantity, uom_id.id)

        if q > process_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The Quantity you entered cannot be more than generated qty (%s)!.') % (process_qty,)
                       }
            min_uom_qty = product_uom_obj._compute_qty(cr, uid, product_uom_asli, 1, uom_id.id)
            if process_qty%min_uom_qty == 0:
                qty_value = product_uom_obj._compute_qty(cr, uid,uom_id.id, process_qty, product_uom_asli)
                uom_value = product_uom_asli
            else:
                uom_value = uom_id.id
                qty_value = process_qty
                unit_price = product_uom_obj._compute_price(cr, uid, product_uom_asli, unit_price,
                        uom_id.id)
            value = {
                     'process_qty' : qty_value,
                     'sel_product_uom' : uom_value,
                     'sel_unit_price' : unit_price,
                    }
            return {'value': value,
                    'warning': warning}

        if product_uom.id != product_uom_asli:
            unit_price = product_uom_obj._compute_price(cr, uid, product_uom_asli, unit_price,
                        product_uom.id)

            value = {
                     'sel_unit_price' : unit_price,
                    }
            return {'value': value}

        return {}
    
    def onchange_process_qty(self, cr, uid, ids, product_uom_asli, process_qty, product_id, quantity, product_uom, unit_price, context=None):
        if context is None:
            context = {}
        value = {}
        product_uom_obj = self.pool.get('product.uom')

        if (not product_id) or (not product_uom):
            value = {
                     'process_qty' : 0.00,
                     'sel_product_uom' : False,
                     'unit_price': 0.00,
                     }
            return {'value': value}
        product_product = self.pool.get('product.product').browse(cr, uid, [product_id])
        uom_id = product_product.uom_id
        product_uom = self.pool.get('product.uom').browse(cr, uid, [product_uom])
        q = product_uom_obj._compute_qty(cr, uid, product_uom.id, quantity, uom_id.id)
        if q > process_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The Quantity you entered cannot be more than generated qty (%s)!.') % (process_qty,)
                       }
            min_uom_qty = product_uom_obj._compute_qty(cr, uid, product_uom_asli, 1, uom_id.id)
            if process_qty%min_uom_qty == 0:
                qty_value = product_uom_obj._compute_qty(cr, uid,uom_id.id, process_qty, product_uom_asli)
                uom_value = product_uom_asli
            else:
                uom_value = uom_id.id
                qty_value = process_qty
                unit_price = product_uom_obj._compute_price(cr, uid, product_uom.id, unit_price,
                        uom_id.id)
            value = {
                     'process_qty' : qty_value,
                     'sel_product_uom' : uom_value,
                     'sel_unit_price' : unit_price,
                    }
            return {'value': value,
                    'warning': warning}
        
        return {}

class param_create_quotation_analytic_service_line(osv.osv_memory):
    _name = 'param.create.quotation.analytic.service.line'
    _description = 'Create Quotation Analytic Service Line'
    
    _columns = {
        'invoice_analytic_service_id': fields.many2one('param.create.invoice.analytic', 'Analytic Service Invoice', ondelete='cascade', readonly=True),
        'product_id': fields.many2one('product.product', 'Product', readonly=True),
        'product_qty': fields.float('Quantity', required=True),
        'real_product_qty': fields.float('Can Process Quantity', readonly=True),
        'unit_price': fields.float('Unit Price',digits_compute= dp.get_precision('Product Price'), required=True),
        'type':fields.selection([('shipyard','Shipyard'),
                                 ('mechanical','Mechanical'),
                                 ('electrical','Electrical'),
                                 ('welding_fabrication','Welding & Fabrication'),
                                 ('interior','Interior'),
                                 ('design','Design')
                                 ], 'Type', readonly=True),
        'analytic_service_line_id': fields.char('Analytic Service Line Id', readonly=True),
    }
    
    def onchange_product_qty(self, cr, uid, ids, real_product_qty, product_qty, context=None):
        if context is None:
            context = {}
         
        value = {}
        warning = {}
         
        if product_qty > real_product_qty:
            warning = {
                       'title': _('Warning'), 
                       'message': _('The Quantity you entered cannot be more than product qty (%s)!.') % (real_product_qty,)
                       }
             
            value = {
                     'product_qty' : real_product_qty,
                    }
         
        return {'value': value,
                'warning': warning}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
